import axios from 'axios'

// 导入vuex中的token,js文件不能用this.$store.state来获取token,建议统一添加到请求拦截器中
import store from '@/store/index'
// 导入路由
import router from '@/router'
import { Toast } from 'vant'
const token = store.state.user.token.token
const refreshToken = store.state.user.token.refresh_token

const instance = axios.create({
  // 根路径
  baseURL: 'http://toutiao.itheima.net',
  // 设置超时时间
  timeout: 5000
})

// 添加请求拦截器
instance.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  // 统一配置token
  if (token) { // 有token就带上，没有就免了
    config.headers.Authorization = 'Bearer ' + token
  }

  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
instance.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response.data
}, async function (error) {
  // 对响应错误做点什么
  // 无感刷新
  if (error.response.status === 401) {
    if (refreshToken) {
      // 本地有refreshToken
      try {
        // 发请求，获取新token
        // 用axios来发请求，因为instance有请求拦截器需要携带token，但是token是过期的
        const res = await axios({
          url: 'http://toutiao.itheima.net/v1_0/authorizations',
          method: 'PUT',
          headers: {
            Authorization: `Bearer ${refreshToken}`
          }
        })
        console.log(res)
        // 将新token存入vuex中
        store.commit('user/removeToken', {
          token: res.data.data.token,
          refresh_token: refreshToken
        })
        // 现在用instance发请求，带上新的token
        return instance(error.config)
      } catch (e) {
        // refresh_token也过期了，拦截到登录页面
        goLogin()
      }
    } else {
      // 没有刷新token，拦截到登录页面
      goLogin()
    }
  }
  return Promise.reject(error)
})
export default instance

function goLogin() {
  // 把vuex和本地存储的token给清除掉 ==> 注意：调用vuex的mutations的removeToken方法，一定要区分是user模块下的mutations方法
  store.commit('user/removeToken')
  // 提示下
  Toast.fail('登录过期，请重新登录')
  // 跳转
  router.push({
    path: '/login',
    query: {
      // 带上回来的地址
      //  问题：在vue组件中，通过 this.$route.fullPath 可以获取到当前路由地址
      //   在js模块中，无法通过this.$route.fullPath 来获取
      //   this.$route 当前路由信息 等价于  router.currentRoute
      back: router.currentRoute.fullPath
    }
  })
}
